package joe.works.pluginframework.support.nshandler;

import joe.works.pluginframework.plugins.StrategyPlugin;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

/**
 * BeanDefinitionParser for strategy tag.
 * <ol>
 * 	<li>&lt;strategy name="strategyName" bean="target" /&gt;</li>
 * 	<li>&lt;strategy name="strategyName" bean="target" order="0"/&gt;</li>
 * </ol>
 * 		
 * @author josseyj
 *
 */
public class StrategyPluginBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser implements BeanDefinitionParser {

	public interface Attributes {
		String STRATEGY_NAME = "name";
		String BEAN = "bean";
		String ORDER = "order";
	}
	
	@Override
	protected Class getBeanClass(Element element) {
		return StrategyPlugin.class;
	}
	
	@Override
	protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
		String strategyName = element.getAttribute(Attributes.STRATEGY_NAME);
		String beanName = element.getAttribute(Attributes.BEAN);
		String order = element.getAttribute(Attributes.ORDER);
		if(strategyName != null && !strategyName.isEmpty()) {
			builder.addPropertyValue("strategyName", strategyName);
		} else {
			throw new IllegalStateException("strategyName not specified.");
		}
		if(beanName != null && !beanName.isEmpty()) {
			builder.addPropertyReference("strategy", beanName);
		} else {
			throw new IllegalStateException("bean not specified.");
		}
		if(order != null && !order.isEmpty()) {
			try {
				int orderNum = Integer.parseInt(order);
				builder.addPropertyValue("order", orderNum);
			} catch(NumberFormatException ex) {
				throw new IllegalStateException("order not a number.");
			}
		}
	}

	@Override
	protected boolean shouldGenerateId() {
		return true;
	}


}